package com.fzf.blog.modules.admin.service.impl;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import com.fzf.blog.core.util.BeanUtil;
import com.fzf.blog.core.util.FcContants;
import com.fzf.blog.core.util.JsonUtil;
import com.fzf.blog.core.util.ReType;
import com.fzf.blog.modules.api.model.BlogDetail;
import com.fzf.blog.modules.api.model.SimpleArticle;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.fzf.blog.modules.admin.mapper.BlogMapper;
import com.fzf.blog.modules.admin.mapper.BlogTypeMapper;
import com.fzf.blog.modules.admin.model.Blog;
import com.fzf.blog.modules.admin.model.BlogType;
import com.fzf.blog.modules.admin.service.BlogService;
import tk.mybatis.mapper.entity.Example;

@Service
public class BlogServiceImpl implements BlogService {

    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private BlogTypeMapper blogTypeMapper;

    public static final AtomicInteger count = new AtomicInteger(0);

    @Override
    public Blog selectBlogById(Integer id) {

        Blog blog = blogMapper.selectBlogById(id);
        if (blog != null) {
            synchronized (blog) {
                count.getAndIncrement();
                blog.setClicknum(blog.getClicknum() + count.get());
                // 十条记录 往数据库写入 一次
                if (count.get() >= 5) {
                    blogMapper.updateBlogSelective(blog);
                    count.set(0);
                }
            }
        }
        return blog;
    }

    public Blog selectBlogUserById(Integer id) {

        Blog blog = blogMapper.selectBlogUserById(id);
        if (blog != null) {
            synchronized (blog) {
                count.getAndIncrement();
                blog.setClicknum(blog.getClicknum() + count.get());
                // 十条记录 往数据库写入 一次
                if (count.get() >= 5) {
                    blogMapper.updateBlogSelective(blog);
                    count.set(0);
                }
            }
        }
        return blog;
    }

    @Override
    public int insertBlog(Blog blog) {

        if (blogMapper.insertBlog(blog) != 0) {
            if (blog.getStatus() == 1) {
                BlogType blogType = blogTypeMapper.selectBlogTypeById(blog.getType().getId());
                blogType.setNum(blogType.getNum() + 1);
                return blogTypeMapper.updateBlogTypeSelective(blogType);
            } else {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public int insertBlogSelective(Blog blog) {

        return blogMapper.insertBlogSelective(blog);
    }

    @Override
    public int deleteBlogById(Integer id) {

        Blog blog = blogMapper.selectBlogById(id);
        if (blogMapper.deleteBlogById(id) != 0) {
            BlogType blogType = blogTypeMapper.selectBlogTypeById(blog.getType().getId());
            blogType.setNum(blogType.getNum() - 1);
            return blogTypeMapper.updateBlogTypeSelective(blogType);
        }
        return 0;
    }

    @Override
    public int updateBlogSelective(Blog blog) {

        Blog oldBlog = blogMapper.selectBlogById(blog.getId());
        if (blog.getType() == null && blog.getStatus() == null) {
            return blogMapper.updateBlogSelective(blog);
        }

        if (blogMapper.updateBlogSelective(blog) != 0) {
            if (blog.getStatus() == 1) {
                if (oldBlog.getStatus() == 1) {
                    BlogType oldBlogType = blogTypeMapper.selectBlogTypeById(oldBlog.getType().getId());
                    oldBlogType.setNum(oldBlogType.getNum() - 1);
                    blogTypeMapper.updateBlogTypeSelective(oldBlogType);
                }
                BlogType blogType = null;
                if (blog.getType() == null) {
                    blogType = blogTypeMapper.selectBlogTypeById(oldBlog.getType().getId());
                } else {
                    blogType = blogTypeMapper.selectBlogTypeById(blog.getType().getId());
                }
                blogType.setNum(blogType.getNum() + 1);
                return blogTypeMapper.updateBlogTypeSelective(blogType);
            } else {
                if (oldBlog.getStatus() == 1) {
                    BlogType oldBlogType = blogTypeMapper.selectBlogTypeById(oldBlog.getType().getId());
                    oldBlogType.setNum(oldBlogType.getNum() - 1);
                    return blogTypeMapper.updateBlogTypeSelective(oldBlogType);
                }
                return 1;
            }
        } else {
            return 0;
        }
    }

    public List<Blog> selectBlogListByPage(Map<String, Object> map) {

        return blogMapper.selectBlogListByPage(map);
    }

    @Override
    public List<Blog> selectBlogByTypeId(Integer id) {

        return blogMapper.selectBlogByTypeId(id);
    }

    @Override
    public Blog selectPrevBlog(Integer id) {

        return blogMapper.selectPrevBlog(id);
    }

    @Override
    public Blog selectNextBlog(Integer id) {

        return blogMapper.selectNextBlog(id);
    }

    @Override
    public List<?> selectBlogListByDate(Map<String, Object> map) {

        return blogMapper.selectBlogListByDate(map);
    }

    @Override
    public Long selectBlogCount(Map<String, Object> map) {

        return null;
    }

    @Override
    public List<Blog> selectLikeBlogListByPage(Map<String, Object> map) {

        return blogMapper.selectLikeBlogListByPage(map);
    }

    @Override
    public List<Blog> selectGroupLikeBlogListByPage(Map<String, Object> map) {

        return blogMapper.selectGroupLikeBlogListByPage(map);
    }

    @Override
    public List<?> selectBlogListByStatus() {

        return blogMapper.selectBlogListByStatus();
    }

    /**
     * 获取博客列表
     *
     * @param searchWord
     */
    @Override
    public ReType selectBySearchWord(String searchWord,Integer page, Integer limit) {
        Page<Object> startPage = PageHelper.startPage(page, limit);
        List<Blog> blogs = blogMapper.selectByKeyWord(searchWord);
        return new ReType(startPage.getTotal(), startPage.getPageNum(), blogs);
    }

    /**
     * 获取博客列表
     *
     * @param page
     * @param limit
     */
    @Override
    @Cacheable(value = FcContants.DEMO_CACHE_NAME, key = "'fc_blog_'+#page")
    public ReType selectAll(Integer page, Integer limit) {
        Page<Object> startPage = PageHelper.startPage(page, limit);
        List<Blog> blogs = blogMapper.selectByKeyWord(null);
        return new ReType(startPage.getTotal(), startPage.getPageNum(), blogs);
    }

    /**
     * 获取博客详情
     *
     * @param ip   访问者ip
     * @param id 博客id
     */
    @Override
    public JsonUtil detail(Integer id, String ip) {
        JsonUtil json = new JsonUtil();
        //点击次数
        addBlogReadNum(ip, id);
        // 获取文章内容
        BlogDetail detail = getArticleByCode(id);
        //上一篇
        Blog prev = blogMapper.selectPrevBlog(id);
        if (prev != null) {
            SimpleArticle simpleArticle = new SimpleArticle();
            BeanUtil.copyNotNullBean(prev, simpleArticle);
            detail.setPrevious(simpleArticle);
        }
        //下一篇
        Blog next = blogMapper.selectNextBlog(id);
        if (next != null) {
            SimpleArticle simpleArticle = new SimpleArticle();
            BeanUtil.copyNotNullBean(next, simpleArticle);
            detail.setNext(simpleArticle);
        }

        json.setData(detail);
        json.setFlag(true);
        return json;

    }


    @Override
    public List<Blog> getArticleByRecommended() {
        Example example = new Example(Blog.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("isrecommend", 1);
        example.setOrderByClause("updatetime desc");
        return blogMapper.selectByExample(example);
    }

    @Override
    public List<Blog> getArticleByReadNumber() {
        Example example = new Example(Blog.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", 1);
        example.setOrderByClause("clicknum desc");
        return blogMapper.selectByExample(example);
    }


    @Override
    public List<Blog> selectLikeBlogListByPageWithBlobs(Map<String, Object> map) {
        return blogMapper.selectLikeBlogListByPageWithBlobs(map);
    }

    @Override
    public List<?> selectBlogByClick() {
        return blogMapper.selectBlogByClick();
    }

    @Override
    public Map<String, List<Blog>> selectBlogByAllType() {
        Map<String, List<Blog>> map = new HashMap<>();
        List<Blog> list = blogMapper.selectBlogByAllType();
        for (Blog blog : list) {
            if (map.containsKey(blog.getType().getTypename())) {
                map.get(blog.getType().getTypename()).add(blog);
            } else {
                List<Blog> bList = new ArrayList<>();
                bList.add(blog);
                map.put(blog.getType().getTypename(), bList);
            }
        }
        return map;
    }


    /**
     * 半小时增加一次有效点击数
     *
     * @param ip 访问者ip
     * @param id 博客id
     */
    //@Cacheable(value = FcContants.DEMO_CACHE_NAME, key = "'readNum_'+#ip+#id")
    public int addBlogReadNum(String ip, Integer id) {
        Blog blog = blogMapper.selectByPrimaryKey(id);
        if (null == blog) {
            return -1;
        }
        blog.setClicknum(blog.getClicknum() + 1);
        return blogMapper.updateBlogSelective(blog);
    }

    private BlogDetail getArticleByCode(Integer code) {
        Blog blog = blogMapper.selectBlogById(code);
        if (null == blog) {
            return null;
        }
        BlogDetail detail = new BlogDetail();
        detail.setBlog(blog);
        detail.setTags(blog.getKeyword().split(","));
        return detail;
    }

}
